package kvpair

import (
	"fmt"
	"io/ioutil"
	"sync"

	"github.com/crate-crypto/go-ipa/ipa"
)

var conf *ipa.IPAConfig

var precompFileName = "precomp"

const POLY_DEGREE = 256

var lock sync.Mutex

// StoreConf store srs
func StoreSRS(srs *ipa.SRSPrecompPoints) error {
	serialized, err := srs.SerializeSRSPrecomp()
	if err != nil {
		return fmt.Errorf("error writing serialized precomputed Lagrange points: %w", err)
	}

	if err = ioutil.WriteFile(precompFileName, serialized, 0555); err != nil {
		return fmt.Errorf("error saving the precomp: %w", err)
	}

	return nil
}

// ReloadConf reload srs
func LoadSRS() (*ipa.SRSPrecompPoints, error) {
	precompSer, err := ioutil.ReadFile(precompFileName)
	if err != nil {
		// 还未存盘
		return nil, fmt.Errorf("load precompute srs failed!")
	}

	srs, err := ipa.DeserializeSRSPrecomp(precompSer)
	if err != nil {
		return nil, fmt.Errorf("error deserializing precomputed Lagrange points, regenerating")
	}
	return srs, nil
}

// GetConf 获取 conf
func GetConf() *ipa.IPAConfig {
	if conf != nil {
		return conf
	}

	lock.Lock()
	defer lock.Unlock()

	if conf != nil {
		// 二次判断
		return conf
	}

	if srs, err := LoadSRS(); nil == err && nil != srs {
		// 加载到存盘信息
		conf = ipa.NewIPASettingsWithSRSPrecomp(srs)
		return conf
	}
	// 重新计算，生成 srs
	srs := ipa.NewSRSPrecomp(POLY_DEGREE)
	conf = ipa.NewIPASettingsWithSRSPrecomp(srs)
	if err := StoreSRS(srs); nil != err {
		panic(err)
	}
	return conf
}
